home *** CD-ROM | disk | FTP | other *** search
- { Semaphor.pas }
- { Copyright 1996, TASC Inc. All rights reserved. }
- { }
- { Created by: Michael T. Nygard }
- { }
- { Version 1.0 }
-
- unit semaphore;
-
- (*
- ** This unit exports the class TSemaphore, an encapsulation of the Win32
- ** semaphore object API. Security descriptors are not supported.
- **
- ** Use Create to construct a new semaphore, use the alternate constructor
- ** Open to access an existing semaphore. After the semaphore is constructed,
- ** use Get and Put to do "downs" and "ups", respectively.
- **
- **
- ** Get - if timeout is 0, the semaphore will not block, but will return
- ** failure immediately if it cannot be acquired. fAlertable will
- ** allow I/O completion routines and other asynchronous alerts to
- ** occur during the WaitForSingleObject.
- **
- ** Put - pass the release count (amount to increment the semaphore). Returns
- ** the previous value.
- *)
-
- interface
-
- uses
- SysUtils, Windows, Classes;
-
- const
- SEMAPHORE_ALL_ACCESS: ULONG = $001F0003;
-
- type
- TSemaphore = class;
-
- ESemaphoreError = class(Exception)
- end;
-
- TSemaphoreEvent = procedure(Sender: TSemaphore) of object;
-
- TSemaphore = class
- private
- FHandle: THandle;
- FName: string;
- FLastStatus: DWORD;
-
- protected
- FOnBeforeGet: TSemaphoreEvent;
- FOnAfterGet: TSemaphoreEvent;
- FOnBeforePut: TSemaphoreEvent;
- FOnAfterPut: TSemaphoreEvent;
-
- function GetLastErrorCode: DWORD; virtual;
-
- public
- constructor Create(const name: string; const initial, max: Longint); virtual;
- constructor Open(const name: string); virtual;
-
- destructor Destroy; virtual;
-
- function Get(timeout: DWORD; bAlertable: boolean): boolean;
- function Put(count: integer): Longint;
-
- property Name: string read FName;
- property Handle: THandle read FHandle;
- property LastStatus: DWORD read FLastStatus;
- property LastError: DWORD read GetLastErrorCode;
- end;
-
- implementation
-
- constructor TSemaphore.Create(const name: string; const initial, max: Longint);
- var
- hTmp: THandle;
- begin
- hTmp := CreateSemaphore(nil, initial, max, PChar(name));
-
- if hTmp = 0 then
- raise ESemaphoreError.Create('Cannot create semaphore.');
-
- FHandle := hTmp;
- end;
-
- constructor TSemaphore.Open(const name: string);
- var
- hTmp: THandle;
- begin
- hTmp := OpenSemaphore(SEMAPHORE_ALL_ACCESS, true, PChar(name));
-
- if hTmp = 0 then
- raise ESemaphoreError.Create('Cannot open semaphore.');
-
- FHandle := hTmp;
- end;
-
- destructor TSemaphore.Destroy;
- begin
- end;
-
- function TSemaphore.Get(timeout: DWORD; bAlertable: boolean): boolean;
- begin
- if Assigned(FOnBeforeGet) then FOnBeforeGet(Self);
-
- FLastStatus := WaitForSingleObjectEx(Handle, timeout, bAlertable);
-
- if (FLastStatus = WAIT_FAILED) or (FLastStatus = WAIT_ABANDONED) or (FLastStatus = WAIT_TIMEOUT) then
- Result := false
- else
- Result := true;
-
- if Assigned(FOnAfterGet) then FOnAfterGet(Self);
- end;
-
- function TSemaphore.Put(count: integer): Longint;
- var
- lastValue: Longint;
- success: boolean;
- begin
- if Assigned(FOnBeforePut) then FOnBeforePut(Self);
-
- success := ReleaseSemaphore(Handle, count, @lastValue);
-
- if success then
- Result := lastValue
- else
- Result := -1;
-
- if Assigned(FOnAfterPut) then FOnAfterPut(Self);
- end;
-
- function TSemaphore.GetLastErrorCode: DWORD;
- begin
- Result := GetLastError;
- end;
-
- end.
-